/*
 * @(#)UsfRedirectUtil.java $version 2010. 8. 11
 *
 * Copyright 2007-2010 NHN Corp. All rights Reserved. 
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.nhncorp.usf.core.web;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.nhncorp.lucy.common.config.model.ApplicationInfo;
import com.nhncorp.lucy.web.dispatcher.RedirectResultInfo;
import com.nhncorp.lucy.web.dispatcher.RedirectUtil;
import com.nhncorp.lucy.web.util.FreeMarkerUtil;

/**
 * @author Web Platform Development Team
 */
public class UsfRedirectUtil extends RedirectUtil {
    private static Log log = LogFactory.getLog(UsfRedirectUtil.class);

    /**
     * GET 방식의 Redirect 시 생성할 페이지에 대한 Freemarker Template
     */
    private static final String ACTION_REDIRECT_GET = "actionRedirectGet.ftl";

    /**
	 * POST 방식의 Redirect 시 생성할 페이지에 대한 Freemarker Template
	 */
	private static final String ACTION_REDIRECT_POST = "actionRedirectPost.ftl";

	/**
     * POST 방식으로 Redirect를 수행할 경우의 {@link RedirectResultInfo}를 생성한다.
     * 
     * @param target the page target
     * @param location the page location
     * @param params the input parameters
     * @return the RedirectResultInfo
     */
    @SuppressWarnings("unchecked")
	public static RedirectResultInfo getFormPage(String target, String location, Map<Object, Object> params) {

		String postTarget = "";

        if (target != null && !target.trim().equals("") && !target.equals("this")) {
			postTarget = "target=\"" + target + "\"";
		}

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("postTarget", postTarget);
		map.put("location", location);

		if (params != null && !params.isEmpty()) {
			List<Object> list = new ArrayList<Object>();
            Iterator iter = params.keySet().iterator();

            while (iter.hasNext()) {
            	String key = (String)iter.next();
				String[] values = getValues(params, key);
    			Map<String, Object> temp = new HashMap<String, Object>();
				temp.put("key", key);
				temp.put("value", values);
				list.add(temp);
			}

            map.put("params", list);
		}

        StringBuffer page = FreeMarkerUtil.processTemplate(ACTION_REDIRECT_POST, map);

		if (page == null) {
			page = new StringBuffer();
        }

        if (log.isDebugEnabled()) {
			log.debug("post request page:\n" + page.toString());
		}

		return new RedirectResultInfo(RedirectResultInfo.TYPE.WRITE_STREAM, page.toString());
	}

    /**
     * GET 방식으로 Redirect를 수행할 경우의 {@link RedirectResultInfo}를 생성한다.
     * lucy-web의 {@link RedirectUtil} 에서 this target 처리를 변경하기 작성된 메서드.
     * 
     * @param target the page path
     * @param src the page path
     * @param params the input parameters
     * @return the RedirectResultInfo
     * @throws UnsupportedEncodingException the UnsupportedEncodingException
     */
    public static RedirectResultInfo getNoFormPage(String target, String src,
                                                   Map<Object, Object> params) throws UnsupportedEncodingException {
        RedirectResultInfo dispatcherType = null;
        String location = null;

        StringBuilder queryString = null;

        if (params != null && params.size() != 0) {
            queryString = new StringBuilder();

            for (Object obj : params.keySet()) {
                String key = (String)obj;
                String[] values = getValues(params, key);

                for (String value : values) {

                    if (queryString.length() != 0) {
                        queryString.append("&");
                    }

                    queryString.append(key).append("=").append(
                            URLEncoder.encode(value, ApplicationInfo.getNativeEncoding()));
                }

            }

            location = src.trim();

            if (location.indexOf("?") < 0) {
                location += "?" + queryString.toString();
            } else {
                if (!location.endsWith("?")) {
                    location += "&";
                }

                location += queryString.toString();
            }
        }

        if (log.isDebugEnabled()) {
            log.debug("redirect path : " + location);
            log.debug("redirect window target : " + target);
        }

        if ("this".equals(target) || "_self".equals(target)) {
            dispatcherType = new RedirectResultInfo(RedirectResultInfo.TYPE.SEND_REDIRECT, location);
        } else {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("path", location);
            map.put("target", target);

            StringBuffer page = FreeMarkerUtil.processTemplate(ACTION_REDIRECT_GET, map);
			
			if (page == null) {
				page = new StringBuffer();
			}

            dispatcherType = new RedirectResultInfo(RedirectResultInfo.TYPE.WRITE_STREAM, page.toString());
        }

        return dispatcherType;
    }

    /**
     * 전달된 map으로 부터 해당 key에 대한 값을 String 배열로 반환한다.
     *
     * @param params parameter 맵
     * @param key    추출하고자 하는 값의 key
     * @return the key array
     */
    private static String[] getValues(Map<Object, Object> params, String key) {
        Object values = MapUtils.getObject(params, key);

        if (values == null) {
            values = new String[] {""};
        } else {
            if (values instanceof String[]) {
                if (((String[])values).length == 0) {
                    values = new String[] {""};
                }
            } else {
                values = new String[] {MapUtils.getString(params, key, "")};
            }
        }

        return (String[])values;
    }
}
